package com.alex.util.date;

import org.apache.commons.lang.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author alex
 */
public class DateUtils {

    public static String YYYYMMDD = "yyyyMMdd";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public synchronized static String format(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        return dateFormat.format(date);
    }

    public synchronized static String format(Date date, String format) {
        if (null == format) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    /**
     * 日期转日期零点
     */
    public synchronized static Date convertDateToMin(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 日期转日期最大
     */
    public synchronized static Date convertDateToMax(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 返回两个日期相差的天数
     *
     * @param before 时间1
     * @param after  时间2
     * @return 相差的天数（正数）
     */
    public synchronized static long daysBetweenNew(Date before, Date after) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        long time1 = 0;
        long time2 = 0;

        try {
            cal.setTime(sdf.parse(sdf.format(before)));
            time1 = cal.getTimeInMillis();
            cal.setTime(sdf.parse(sdf.format(after)));
            time2 = cal.getTimeInMillis();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Math.abs(between_days);
    }

    /**
     * 获取当前Calendar
     *
     * @return 当前Calendar
     */
    public synchronized static Calendar getCurrentCalendar() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        return calendar;
    }

    /**
     * 日期间隔秒数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public synchronized static Long calLastedTime(Date startDate, Date endDate) {
        long a = startDate.getTime();
        long b = endDate.getTime();
        long c = (long) ((a - b) / 1000);
        return c;
    }

    /**
     * 时间转字符串
     *
     * @param aDate
     * @return
     */
    public synchronized static String convertDateToString(String pattern, Date aDate) {
        return getDateTime(pattern, aDate);
    }

    public synchronized static String getDateTime(String aMask, Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (aDate == null) {
            return returnValue;
        } else {
            df = new SimpleDateFormat(aMask);
            returnValue = df.format(aDate);
        }
        return returnValue;
    }

    /**
     * 时间戳转字符串
     *
     * @param time
     * @param format
     * @return
     * @throws ParseException
     */
    public synchronized static Date formatTimeStamp(String time, String format) throws ParseException {
        Long date = Long.parseLong(time);
        if (null == format) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        String format1 = dateFormat.format(date);
        return dateFormat.parse(format1);
    }

    /**
     * 两个时间相差小时
     *
     * @param before
     * @param after
     * @return
     */
    public synchronized static int hourBetween(Date before, Date after) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        long time1 = 0;
        long time2 = 0;

        try {
            cal.setTime(sdf.parse(sdf.format(before)));
            time1 = cal.getTimeInMillis();
            cal.setTime(sdf.parse(sdf.format(after)));
            time2 = cal.getTimeInMillis();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long between_hour = (time2 - time1) / (1000 * 3600);

        return Integer.parseInt(String.valueOf(between_hour)) + 1;
    }

    public synchronized static String formatTimeString(String time, String format) {
        Long date = Long.parseLong(time);
        if (null == format) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    public synchronized static Date parse(String date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = null;
        try {
            parse = dateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    public synchronized static Date parse(String date, String format) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.parse(date);
    }

    public synchronized static Date today() throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.parse(dateFormat.format(new Date()));
    }

    public synchronized static Date addDays(Date date, long daySpan) {
        if (null == date) {
            return null;
        }
        String s_date1 = format(date);
        Date round_date1 = parse(s_date1);

        round_date1.setTime(round_date1.getTime() + (daySpan * 24 * 60 * 60 * 1000));
        return round_date1;
    }

    public synchronized static Integer day(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_MONTH);
    }

    public synchronized static Integer month(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }

    public synchronized static Integer year(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.YEAR);
    }

    public synchronized static Integer dayspan(Date date1, Date date2) {
        String s_date1 = format(date1);
        String s_date2 = format(date2);

        Date round_date1 = parse(s_date1);
        Date round_date2 = parse(s_date2);
        return (int) Math.abs((round_date2.getTime() - round_date1.getTime()) / (24 * 60 * 60 * 1000));
    }

    public synchronized static Integer timeSpan(Date date1, Date date2) {

        return (int) Math.abs((date1.getTime() - date2.getTime()) / (1000));

    }

    public synchronized static Date setTimeToMidnight(Date date) {
        if (null == date) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 日期转换成字符串
     *
     * @param date
     * @param format
     * @return
     */
    public synchronized static String dateToString(Date date, String format) {
        if (null == format) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat df = new SimpleDateFormat(format);

        return df.format(date);
    }

    /**
     * 字符串转换成日期
     *
     * @param date
     * @param format
     * @return
     */
    public synchronized static Date stringToDate(String date, String format) {
        if (null == format) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat df = new SimpleDateFormat(format);

        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param formatString
     * @param strDate
     */
    public synchronized static Date convertStringToDate(String formatString, String strDate) {
        if (StringUtils.isBlank(strDate)) {
            throw new IllegalArgumentException("arg strDate[" + strDate + "] format is wrong");
        }
        if (StringUtils.isBlank(formatString)) {
            throw new IllegalArgumentException("arg formatString[" + formatString + "] format is wrong");
        }

        SimpleDateFormat df = new SimpleDateFormat(formatString);
        Date date = null;

        try {
            date = df.parse(strDate);
        } catch (ParseException ex) {
            throw new IllegalArgumentException("arg formatString[" + formatString + "] format is wrong", ex);
        }

        return (date);
    }

    public synchronized static Date addDate(int day) {
        Date beginDate = new Date();
        Calendar date = Calendar.getInstance();
        date.setTime(beginDate);
        date.set(5, date.get(5) + day);
        return date.getTime();
    }

    public synchronized static Date addDate(Date beginDate, int day) {
        Calendar date = Calendar.getInstance();
        date.setTime(beginDate);
        date.set(5, date.get(5) + day);
        return date.getTime();
    }

    /**
     * 改变时间分钟
     *
     * @param beginDate
     * @param minute
     * @return
     */
    public synchronized static Date updateDateMinute(Date beginDate, int minute) {
        Calendar date = Calendar.getInstance();
        date.setTime(beginDate);
        date.add(Calendar.MINUTE, minute);
        return date.getTime();
    }

    public synchronized static Date modifyDateByString(String beginDate, int day) {
        Calendar date = Calendar.getInstance();
        date.setTime(new Date(Long.valueOf(beginDate)));
        date.set(5, date.get(5) + day);
        return date.getTime();
    }

    public synchronized static Date add(Date date, int field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    /**
     * 给时间加上指定分钟
     *
     * @param date  当前时间 格式：yyyy-MM-dd HH:mm:ss
     * @param minut 需要加的时间
     * @return
     */
    public synchronized static Date addDateMinut(Date date, int minut) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 24小时制
        cal.add(Calendar.MINUTE, minut);
        return cal.getTime();

    }

    /**
     * 设备同步时间加上5分钟大于当前时间表示设备在线
     *
     * @param dateTime
     * @return
     */
    public synchronized static boolean IsDeviceOnline(Date dateTime) {
        boolean bo = false;
        try {
            long nowTime = System.currentTimeMillis();
            long afterTime = dateTime.getTime();
            afterTime = afterTime + 300000;
            if (afterTime > nowTime) {
                bo = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bo;
    }

    /**
     * 计算是否已超退款时间
     *
     * @param dateTime
     * @param addMinute
     * @return
     */
    public synchronized static boolean IsRefuund(Date dateTime, int addMinute) {
        boolean bo = false;
        try {
            //计算毫秒
            int millisecond = (addMinute * 60) * 1000;
            Date nextDate = new Date(dateTime.getTime() + millisecond);
            if (nextDate.getTime() > System.currentTimeMillis()) {
                bo = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bo;
    }

    /**
     * 获取当前时间：年月日时分秒
     */
    public synchronized static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDD);
    }

    public synchronized static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public synchronized static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    /**
     * 获取本月最小的一天
     *
     * @return
     */
    public synchronized static Date monthMinDay(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        return cale.getTime();
    }

    /**
     * 获取本月最大的一天
     *
     * @return
     */
    public synchronized static Date monthMaxDay(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        return cale.getTime();
    }

    /**
     * 功能描述：返回分
     *
     * @param date 日期
     * @return 返回分钟
     */
    public synchronized static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 返回秒钟
     *
     * @param date Date 日期
     * @return 返回秒钟
     */
    public synchronized static int getSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

}
